package com.upb.webserver.appmarket;

import cn.hutool.core.util.ZipUtil;
import com.upb.webserver.common.pojo.appmarket.AppContract;
import com.upb.webserver.common.pojo.appmarket.AppDocument;
import com.upb.webserver.common.pojo.appmarket.AppInfo;
import com.upb.webserver.common.pojo.base.BaseResponse;
import com.upb.webserver.common.returncode.ConstantCode;
import com.upb.webserver.common.tools.JsonUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.security.spec.InvalidKeySpecException;
import java.util.List;

/**
 * market of app.
 */
@Log4j2
@RestController
@RequestMapping(value = "market/app")
public class AppMarketController {
    @Autowired
    private AppMarketService appMarketService;

    /**
     * 获取应用市场的所有应用列表。
     *
     * @return
     */
    @GetMapping(value = "/all")
    public BaseResponse getAllAppInfo() {
        log.info("start exec method [getAllAppInfo]. ");

        List<AppInfo> appInfoList = appMarketService.getAllAppInfo();
        BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS);
        baseResponse.setData(appInfoList);
        log.info("success exec method [getAllAppInfo]. baseResponse:{}", JsonUtils.objToString(baseResponse));
        return baseResponse;
    }


    @GetMapping(value = "/{appName}/document/all")
    public BaseResponse getAllDocumentByAppName(@PathVariable("appName") String appName) {
        log.info("start exec method [getAllDocumentByAppName]. appName:{}", appName);
        List<AppDocument> documentList = appMarketService.getAllDocumentByAppName(appName);
        BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS);
        baseResponse.setData(documentList);
        log.info("success exec method [getAllDocumentByAppName]. baseResponse:{}", JsonUtils.objToString(baseResponse));
        return baseResponse;
    }


    /**
     * 根据应用名称，获取应用下的所有合约。
     *
     * @param appName
     * @return
     */
    @GetMapping(value = "/{appName}/contract/all")
    public BaseResponse getAllContractByAppName(@PathVariable("appName") String appName) {
        log.info("start exec method [getAllContractByAppName]. appName:{}", appName);
        List<AppContract> contractInfoList = appMarketService.getAllContractByAppName(appName);
        BaseResponse baseResponse = new BaseResponse(ConstantCode.SUCCESS);
        baseResponse.setData(contractInfoList);
        log.info("success exec method [getAllContractByAppName]. baseResponse:{}", JsonUtils.objToString(baseResponse));
        return baseResponse;
    }


    /**
     * 根据应用名称，下载应用下的所有合约。
     *
     * @param appName
     * @param response
     * @throws InvalidKeySpecException
     * @throws UnsupportedEncodingException
     */
    @GetMapping("/{appName}/contract/all/download")
    public void downLoadContractByAppName(@PathVariable("appName") String appName, HttpServletResponse response) throws InvalidKeySpecException, UnsupportedEncodingException {
        log.info("start exec method [downLoadContractByAppName]. appName:{}", appName);

        File file = appMarketService.getContractDirectoryByAppName(appName);
        String ZipFilePath = Paths.get(file.getParent(), appName) + "Contract.zip"; //压缩包以应用名称命名
        File zipFile = new File(ZipFilePath);
        ZipUtil.zip(file.getPath(), ZipFilePath, false);//将源文件目录下文件打包到指定目录（如果存在同名压缩文件，会覆盖），不包含被打包目录

        //response
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
        response.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(appName, StandardCharsets.UTF_8.toString()) + "Contract.zip");
        response.setHeader("fileName", java.net.URLEncoder.encode(appName, StandardCharsets.UTF_8.toString()));
        byte[] buffer = new byte[1024];
        try (FileInputStream fis = new FileInputStream(zipFile);
             BufferedInputStream bis = new BufferedInputStream(fis);
             OutputStream os = response.getOutputStream()) {
            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer);
                i = bis.read(buffer);
            }
        } catch (Exception e) {
            log.warn("fail exec method [downLoadContractByAppName]. appName:{}", appName, e);
        }
    }


    /**
     * 根据应用名称，下载应用下的所有文档。
     *
     * @param appName
     * @param response
     * @throws InvalidKeySpecException
     * @throws UnsupportedEncodingException
     */
    @GetMapping("/{appName}/document/all/download")
    public void downLoadDocumentByAppName(@PathVariable("appName") String appName, HttpServletResponse response) throws InvalidKeySpecException, UnsupportedEncodingException {
        log.info("start exec method [downLoadDocumentByAppName]. appName:{}", appName);

        File file = appMarketService.getDocumentDirectoryByAppName(appName);
        String ZipFilePath = Paths.get(file.getParent(), appName) + "Document.zip"; //压缩包以应用名称命名
        File zipFile = new File(ZipFilePath);
        ZipUtil.zip(file.getPath(), ZipFilePath, false);//将源文件目录下文件打包到指定目录（如果存在同名压缩文件，会覆盖），不包含被打包目录

        //response
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
        response.setHeader("Content-Disposition", "attachment;fileName=" + java.net.URLEncoder.encode(appName, StandardCharsets.UTF_8.toString()) + "Document.zip");
        response.setHeader("fileName", java.net.URLEncoder.encode(appName, StandardCharsets.UTF_8.toString()));
        byte[] buffer = new byte[1024];
        try (FileInputStream fis = new FileInputStream(zipFile);
             BufferedInputStream bis = new BufferedInputStream(fis);
             OutputStream os = response.getOutputStream()) {
            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer);
                i = bis.read(buffer);
            }
        } catch (Exception e) {
            log.warn("fail exec method [downLoadDocumentByAppName]. appName:{}", appName, e);
        }
    }
}
